<?php

namespace App\Http\Controllers\Api\Mobile;

use Illuminate\Support\Facades\Cache;
use App\Models\Order;
use App\Models\Domain;
use App\Models\User;
use App\Models\Video;
use App\Models\PayMethod;
use Yansongda\Pay\Pay;
use Yansongda\Pay\Log;
use Illuminate\Http\Request;
use Carbon\Carbon;
use App\Models\BadOpenid;

use App\Services\PayService;
use App\Jobs\CreateOrder;
use App\Jobs\UpdateOrder;


class PayController extends Controller
{
    /**
     * 微信支付回调
     *
     * @return void
     */
    public function wxPayNotify()
    {
        $pay = Pay::wechat((new PayService())->getWxPayConfig());

        try{
            $data = $pay->verify(); // 是的，验签就这么简单！
            $order = Order::where('no', $data->out_trade_no)->first();
            if (!$order) {
                return 'fail';
            }

            // 订单已支付
            if ($order->paid_at && $order->valid==1) {
                // 告知微信支付此订单已处理
                return $pay->success();
            }

            // 将订单标记为已支付 --队列执行
            $order['no'] = $data->out_trade_no;
            $order['transaction_id'] = $data->transaction_id;
            UpdateOrder::dispatch($order);
            // 订单队列结束

        } catch (\Exception $e) {
            \Log::error($e->getMessage());
            return 'fail';
        }
        return $pay->success();// 告知微信支付此订单已处理
    }

    /**
     * 
     *
     * @param Request $request
     * @return void
     */
    public function getPay(Request $request){
        //视频ID
        $video_id = $request->video_id;
        //视频
        $video = Video::show()->where('id',$video_id)->first();
        //校验身份
        $code = $request->code;

        //解析code
        $code_data = decodeCode($code);
        // $openid = $code_data[2];
        //获取支付方式
        $pay_method = (new PayService())->getPayMethod();
        if($pay_method['type']=='' || count($pay_method['config'])<=0){
            cache()->forget('pay_method');    
            return false;        
        }
        //订单号
        $no = createOrderNo().str_pad($request->video_id, 5, '0', STR_PAD_LEFT);
        $ip = getIp();
        $ua = $_SERVER['HTTP_USER_AGENT'];
        // 订单信息
        $order =[
            'agent_id'=>$code_data[1],
            'openid'=>$request->pay_openid,
            'video_id'=>$video['id'],
            'code' =>$code,
            'no'=>$no,
            'price'=>$request->price,
            'agent_price'=>$request->price,
            'appid'=>$pay_method['config']['appid']??'',
            'mch_id'=>$pay_method['config']['mchid'],
            'type'=>$pay_method['type']??'',
            'ip'=>$ip,
            'ua'=>$ua
        ];
        // 队列执行创建订单
        CreateOrder::dispatch($order);
        // 订单队列结束
        //微信内付
        $result = $this->wxpay($order);
        if(!$result['error']){
            $res['status'] = 1;
            $res['config'] = $result['config'];
            $res['no'] = $no;
            $res['type'] = 'wx';
            return $res;
        }else{
            $res['msg'] = $result['msg'];
            $res['status'] = -1;
            return $res;
        }
    }

    /**
     * 微信支付config
     *
     * @param [type] $order_data
     * @return void
     */
    public function wxpay($order_data){
        $titles = config('visit.paytitles');
        $title = $titles[array_rand($titles)];
        $order = [
            'out_trade_no' => $order_data['no'],
            'total_fee' => $order_data['price']*100, // **单位：分**
            'body' => $title,
            'openid' => $order_data['openid'],
        ];
        try{
            $result = Pay::wechat((new PayService())->getWxPayConfig())->mp($order);
            $res=[
                'error'=>false,
                'config'=>$result
            ];
            return $res;
        }catch(\Exception $e){
            \Log::debug($e->getMessage());
            $res=[
                'error'=>true,
                'msg'=>$e->getMessage()
            ];
            return $res;
        }
    }


    /**
     * 微信内付查询订单
     *
     * @return void
     */
    public function queryPay(Request $request){
        $video_id = $request->video_id;
        $order_no = [
            'out_trade_no' => $request->no,
        ];
        $wechat = Pay::wechat((new PayService())->getWxPayConfig());
        $result = $wechat->find($order_no);
        if($result->return_code=="SUCCESS" && $result->trade_state == "SUCCESS"){
            //校验身份
            $code = $request->code;
            //解析code
            $code_data = decodeCode($code);
            $openid = $code_data[2];
            // 将订单标记为已支付 --队列执行
            $order['code'] = $request->code;
            $order['no'] = $request->no;
            $order['transaction_id'] = $result->transaction_id;
            UpdateOrder::dispatch($order);
            // 订单队列结束
            //保存缓存
            cache()->put("paid:{$openid}:{$video_id}", 1, now()->addMinutes(10));
            //返回
            $data['trade_state'] = 'success';
            return $this->success($data);
        }
        return $this->errMsg('支付失败');
    }



    ///////////////////////////////////// 小程序支付查单 //////////////////////////////////////////////

    //查询
    public function miniPayQuery(Request $request){
        $order = Order::where('no',$request->no)->first()->toArray();
        if($order['paid_at']){
            $data['trade_state'] = 'success';
            return $this->success($data);
        }
        $data['trade_state'] = 'fail';
        return $this->success($data);
    }

    //回调
    public function miniPayNotify(Request $request){
        $order = Order::where('no',$request->no)->first();
        if($order){
            $code = createCode($order->agent_id,$order->openid);
            $video_id = $order->video_id;
            //保存缓存
            cache()->put("paid:{$order->openid}:{$video_id}", 1, now()->addMinutes(30));
            // 将订单标记为已支付 --队列执行
            $order['code'] = $code;
            $order['no'] = $no;
            $order['transaction_id'] = '来自小程序';
            UpdateOrder::dispatch($order);
            return 'success';
        }else{
            return 'fail';
        }
    }
    


    ///////////////////////////////// 扫码通道 //////////////////////////////////////////////////
    
    /*
     扫码视图
    */
    public function sevenQrcode(Request $request){
        $data = $request->all();
        return view('mobile.pay.sevenSm.qrcode',compact('data'));
    }

    //扫码之后同步跳转
    public function sevenSuccess(Request $request)
    {
        $no = $request->no;
        $order = Order::where('no',$no)->first();
        $video_id = $order->video_id;
        //获取落地
        $born_domain = cache()->rememberForever('born_domain',  function () {
            //落地有可能没有了，所以加锁防止没有时缓存穿透
            return cache()->lock('born_domain')->get(function () {
                // 获取无限期锁并自动释放...
                return Domain::show()->born()->orderBy('sort')->value('domain');
            });
        });
        //保存缓存
        cache()->put("paid:{$order->openid}:{$video_id}", 1, now()->addMinutes(30));
        $code = createCode($order->agent_id,$order->openid);
        $url = "http://{$born_domain}/play?code={$code}&video_id={$video_id}";
        return redirect($url);
    }
    //扫码后台通知
    public function sevenNotify(Request $request)
    {
        // [2021-05-21 19:34:42] production.DEBUG: array (
        //     'mchId' => '600500172',
        //     'tradeNo' => '472479877065621504',
        //     'billNo' => '202105211831121057277102019',
        //     'sub_op' => '600500172',
        //     'totalAmount' => '1.00',
        //     'transferId' => '-DNFDQ-20210521-IVD0Adq5s717',
        //     'way' => 'qrcode',
        //     'payment' => 'wechat',
        //     'code' => 'Tengxun_two',
        //     'acc_key' => 'D521710295842602',
        //     'acc_name' => '1297774076',
        //     'attach' => NULL,
        //     'tradeStatus' => '1',
        //     'create_at' => '1621593073',
        //     'payTime' => '1621593116',
        //     'sign' => '40523716C02E5254A97F26DA77036987',
        //   ) 
        $inputs=$request->all();
        $order_no = $inputs["billNo"]; //商户订单号
        $tradeStatus = $inputs["tradeStatus"]; //支付成功状态

        if ($tradeStatus==1){
            $order = Order::where('no',$order_no)->first()->toArray();
            
            if($order['paid_at']){
                return 'success';
            }
            // 将订单标记为已支付 --队列执行
            $order['transaction_id'] = $inputs['tradeNo'];
            UpdateOrder::dispatch($order);
            //商户处理订单逻辑
            return 'success';
        }
        return 'fail';
    }


     ///////////////////////////////// 和珅支付通道 //////////////////////////////////////////////////
    

    //和珅支付页面跳转
    public function hsSuccess(Request $request)
    {
        $inputs=$request->all();
        if($inputs['trade_status']=='TRADE_SUCCESS'){
            $no = $inputs['out_trade_no'];
            $order = Order::where('no',$no)->first();
            if($order){
                $code = createCode($order->agent_id,$order->openid);
                $video_id = $order->video_id;
                //获取落地
                $born_domain = cache()->rememberForever('born_domain',  function () {
                    //落地有可能没有了，所以加锁防止没有时缓存穿透
                    return cache()->lock('born_domain')->get(function () {
                        // 获取无限期锁并自动释放...
                        return Domain::show()->born()->orderBy('sort')->value('domain');
                    });
                });
                //保存缓存
                cache()->put("paid:{$order->openid}:{$video_id}", 1, now()->addMinutes(30));
                // 将订单标记为已支付 --队列执行
                $order['code'] = $code;
                $order['no'] = $no;
                $order['transaction_id'] = $inputs['trade_no'];
                UpdateOrder::dispatch($order);
                // 订单队列结束
                $url = "http://{$born_domain}/play?code={$code}&video_id={$video_id}";
                return redirect($url);
            }else{
                return back();
            }
        }else{
            return back();
        }
    }

    
    /**
     * 和珅支付回调
     *
     * @return void
     */
    public function hsPayNotify(Request $request)
    {
        $inputs = $request->all();
        \Log::debug($inputs);
        return true;
    }
}
